package com.liufh.aop;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.util.Arrays;

/**
 * @author: liufh
 * @create: 2021-09-16 15:14
 */
@Component
@Aspect
public class AnnLogAspect {

    @Pointcut("execution(* com.liufh.service.*.*(..))")
    public void pointcut(){}

    @Before("pointcut()")
    public void beforePrintLog(JoinPoint jp){
        Object[] args = jp.getArgs();
        System.out.println("@Before前置通知：beforePrintLog，参数是："+ Arrays.toString(args));
    }

    @AfterReturning(value = "pointcut()",returning = "rtValue")
    public void afterReturningPrintLog(Object rtValue){
        System.out.println("@AfterReturning后置通知：afterReturningPrintLog，返回值是："+rtValue);
    }

    @AfterThrowing(value = "pointcut()",throwing = "e")
    public void afterThrowingPrintLog(Throwable e){
        System.out.println("@AfterThrowing异常通知：afterThrowingPrintLog，异常是："+e);
    }

    @After("pointcut()")
    public void afterPrintLog(){
        System.out.println("@After最终通知：afterPrintLog");
    }

    @Around("pointcut()")
    public Object aroundPrintLog(ProceedingJoinPoint pjp){
        long startTime = System.currentTimeMillis();
        //定义返回值
        Object rtValue = null;
        try {
            System.out.println("@Around前置通知");
            //1.获取参数
            Object[] args = pjp.getArgs();
            //2.执⾏切⼊点⽅法
            rtValue = pjp.proceed(args);
            System.out.println("@Around后置通知");
        } catch (Throwable t){
            System.out.println("@Around异常通知");
            t.printStackTrace();
        } finally {
            System.out.println("@Around最终通知");
        }

        long diffTime = System.currentTimeMillis() - startTime;
        MethodSignature signature = (MethodSignature) pjp.getSignature();
        String methodName = signature.getDeclaringTypeName() + "." + signature.getName();
        System.out.println(methodName + "耗时：" + diffTime + "ms");

        return rtValue;
    }

}
